package com.jeeplus.modules.statistics.service;

import com.jeeplus.common.utils.DateUtils;
import com.jeeplus.common.utils.time.DateUtil;
import com.jeeplus.database.datasource.annotation.DS;
import com.jeeplus.modules.statistics.model.enumeration.QueryParamsEnum;
import com.jeeplus.modules.statistics.mapper.AgeMapper;
import com.jeeplus.modules.statistics.mapper.BusinessTrendsMapper;
import com.jeeplus.modules.statistics.mapper.HotBusinessMapper;
import com.jeeplus.modules.statistics.model.domain.AgeCount;
import com.jeeplus.modules.statistics.model.domain.BusinessTrends;
import com.jeeplus.modules.statistics.model.domain.HotBussinessCount;
import com.jeeplus.modules.statistics.model.query.HomeStatisticsQuery;
import com.jeeplus.modules.statistics.model.vo.HomeCharts;
import com.jeeplus.modules.statistics.model.vo.StatisticsXY;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 领导看板-主页
 *
 * @author hanKongBin
 * @version 1.0
 * @date 2021/3/6 15:39
 */
@DS("queuing")
@Service
@AllArgsConstructor
@Slf4j
public class LeaderBoradService {

    private final HotBusinessMapper hotBusinessMapper;

    private final BusinessTrendsMapper businessTrendsMapper;

    private final AgeMapper ageMapper;


    /**
     * 获取图表
     *
     * @param query
     * @return
     */
    public HomeCharts findCharts(HomeStatisticsQuery query) {
        HomeCharts homeCharts = new HomeCharts();
        try {
            homeCharts.setChart1(this.hotBusinessTop(query));
        } catch (Exception e) {
            e.printStackTrace();
            log.error("主页-热度业务top10失败->{}", e.getMessage());
        }
        try {
            homeCharts.setChart2(this.serverTimesTrends(query));
        } catch (Exception e) {
            e.printStackTrace();
            log.error("主页-业务办理趋势失败->{}", e.getMessage());
        }
        try {
            homeCharts.setChart3(this.age(query));
        } catch (Exception e) {
            e.printStackTrace();
            log.error("主页-年龄统计失败->{}", e.getMessage());
        }
        return homeCharts;
    }

    /**
     * 热度业务Top10统计
     *
     * @param query
     * @return
     */
    private StatisticsXY hotBusinessTop(HomeStatisticsQuery query) throws Exception {
        List<String> xValue = new ArrayList<>();
        List<Long> yValue = new ArrayList<>();
        // 取前10
        int topNum = 10;
        List<HotBussinessCount> dataObj = hotBusinessMapper.homeStatistics(query);
        if (dataObj.size() > topNum) {
            dataObj = dataObj.stream().limit(topNum).collect(Collectors.toList());
        }
        for (HotBussinessCount datum : dataObj) {
            StringBuilder xLabel = new StringBuilder();
            // 拼接x轴数据 例:社保服务(A)
            Optional.ofNullable(datum.getBusName()).ifPresent(xLabel::append);
            Optional.ofNullable(datum.getBusChar()).ifPresent(e -> xLabel.append("(").append(e).append(")"));
            xValue.add(xLabel.toString());
            yValue.add(datum.getNumber());
        }
        return new StatisticsXY(xValue, yValue);
    }


    /**
     * 业务办理趋势统计
     *
     * @param query
     * @return
     */
    private StatisticsXY serverTimesTrends(HomeStatisticsQuery query) throws Exception {
        List<String> xValue = new ArrayList<>();
        List<Long> yValue = new ArrayList<>();
        coverParams(query);
        List<BusinessTrends> businessTrends = businessTrendsMapper.serverTimesTrends(query);
        for (BusinessTrends datum : businessTrends) {
            String xLabel = datum.getServerTime();
            long yLabel = datum.getNumber();
            if (QueryParamsEnum.CURRENT_DAY.getCode().equals(query.getCurrentFlag())) {
                // 设置时段 10点-11点
                int period = Integer.parseInt(xLabel);
                xLabel = period + "点-" + (period + 1) + "点";
            }
            xValue.add(xLabel);
            yValue.add(yLabel);
        }
        return new StatisticsXY(xValue, yValue);
    }

    /**
     * 年龄统计
     *
     * @param query
     * @return
     */
    private List<Map<String, Long>> age(HomeStatisticsQuery query) {
        List<Map<String, Long>> data = new ArrayList<>();
        try {
            List<AgeCount> ageCounts = ageMapper.homeStatistics(query);
            for (AgeCount ageCount : ageCounts) {
                Map<String, Long> map = new HashMap<>();
                map.put(ageCount.getAge(), ageCount.getNumber());
                data.add(map);
            }
        } catch (Exception e) {
            e.printStackTrace();
            log.error("年龄统计失败->{}", e.getMessage());
        }
        return data;
    }

    /**
     * 根据本年、本月、本周、当日设置对应的开始日期和结束日期查询参数
     *
     * @param query
     */
    private void coverParams(HomeStatisticsQuery query) {
        if (null == query.getCurrentFlag()) {
            // 同一天
            boolean isSameDay = DateUtil.isSameDate(DateUtils.parseDate(query.getStartTime()), DateUtils.parseDate(query.getEndTime()));
            // 同一年
            boolean isSameYear = DateUtil.isSameYear(DateUtils.parseDate(query.getStartTime()), DateUtils.parseDate(query.getEndTime()));
            // 同一年
            boolean isSameMonth = DateUtil.isSameMonth(DateUtils.parseDate(query.getStartTime()), DateUtils.parseDate(query.getEndTime()));
            if (isSameDay) {
                query.setCurrentFlag(QueryParamsEnum.CURRENT_DAY.getCode());
                return;
            }
            if(!isSameYear){
                query.setCurrentFlag(QueryParamsEnum.CURRENT_LAST_YEAR.getCode());
            }
            if(isSameYear && !isSameMonth){
                query.setCurrentFlag(QueryParamsEnum.CURRENT_YEAR.getCode());
            }
            return;
        }
        QueryParamsEnum paramsEnum = QueryParamsEnum.getTypeByCode(query.getCurrentFlag());
        if (null == paramsEnum) {
            return;
        }
        // 结束日期设置为当前日期
        query.setEndTime(DateUtils.getDate(DateUtils.DEFAULT_PATTERN));
        // 根据枚举值设置开始日期
        switch (paramsEnum) {
            case CURRENT_YEAR:
                query.setStartTime(DateUtils.getYear());
                break;
            case CURRENT_MONTH:
                query.setStartTime(DateUtils.getYear() + "-" + DateUtils.getMonth() + "-01");
                break;
            case CURRENT_WEEK:
                query.setStartTime(DateUtils.formatDate(DateUtils.getTimesWeekmorning(), DateUtils.DEFAULT_PATTERN));
                break;
            case CURRENT_DAY:
                query.setStartTime(DateUtils.formatDate(new Date(), DateUtils.PATTERN_YYYYMMDD));
                break;
            default:
                break;
        }
    }
}
